;;; GNU Guix --- Functional package management for GNU
;;;
;;; Copyright © 2021 Raghav Gururajan <rg@raghavgururajan.name>
;;;
;;; This file is not part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guixrus packages linux-hardware)
  #:use-module (guix build-system perl)
  #:use-module (guix git-download)
  #:use-module (guix packages)
  #:use-module (guix utils)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages avahi)
  #:use-module (gnu packages base)
  #:use-module (gnu packages bash)
  #:use-module (gnu packages cups)
  #:use-module (gnu packages curl)
  #:use-module (gnu packages debian)
  #:use-module (gnu packages disk)
  #:use-module (gnu packages freedesktop)
  #:use-module (gnu packages gl)
  #:use-module (gnu packages gnome)
  #:use-module (gnu packages hardware)
  #:use-module (gnu packages linux)
  #:use-module (gnu packages package-management)
  #:use-module (gnu packages pciutils)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages scanner)
  #:use-module (gnu packages security-token)
  #:use-module (gnu packages video)
  #:use-module (gnu packages vulkan)
  #:use-module (gnu packages web)
  #:use-module (gnu packages xorg))

(define-public hw-probe
  (package
    (name "hw-probe")
    (version "1.5")
    (source
     (origin
       (method git-fetch)
       (uri
        (git-reference
         (url "https://github.com/linuxhw/hw-probe")
         (commit version)))
       (file-name (git-file-name name version))
       (sha256
        (base32 "1zyaardfw6r9nwxbkbb68hyl8719xn8sxpbgm7czkvsbjrim11n8"))))
    (build-system perl-build-system)
    (arguments
     `(#:tests? #f                      ;no test target
       #:imported-modules
       (,@%perl-build-system-modules)
       #:modules
       ((guix build perl-build-system)
        (guix build utils)
        (srfi srfi-26))
       #:phases
       (modify-phases %standard-phases
         (add-after 'unpack 'patch
           (lambda* (#:key inputs outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out")))
               ;; Correct install prefix.
               (substitute* "Makefile"
                 (("/usr") out)))
             ;; Use absolute paths to referenced programs.
             ;; FIXME: Some programs are to be patched successfully,
             ;; and some other programs are to be packaged in Guix.
             (substitute* "hw-probe.pl"
               (("Cmd\\(\"acpi")
                (format #f "Cmd(\"~a/bin/acpi"
                        (assoc-ref inputs "acpi")))
               (("Cmd\\(\"acpidump")
                (format #f "Cmd(\"~a/bin/acpidump"
                        (assoc-ref inputs "acpica")))
               (("Cmd\\(\"acpixtract")
                (format #f "Cmd(\"~a/bin/acpixtract"
                        (assoc-ref inputs "acpica")))
               (("Cmd\\(\"alsactl")
                (format #f "Cmd(\"~a/bin/alsactl"
                        (assoc-ref inputs "alsa-utils")))
               #;(("Cmd\\(\"amdconfig")
               (format #f "Cmd(\"~a/bin/amdconfig" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"amixer")
                (format #f "Cmd(\"~a/bin/amixer"
                        (assoc-ref inputs "alsa-utils")))
               #;(("Cmd\\(\"apk")
               (format #f "Cmd(\"~a/bin/apk" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"aplay")
                (format #f "Cmd(\"~a/bin/aplay"
                        (assoc-ref inputs "alsa-utils")))
               #;(("Cmd\\(\"arcconf")
               (format #f "Cmd(\"~a/bin/arcconf" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"arecord")
                (format #f "Cmd(\"~a/bin/arecord"
                        (assoc-ref inputs "alsa-utils")))
               (("Cmd\\(\"avahi-browse")
                (format #f "Cmd(\"~a/bin/avahi-browse"
                        (assoc-ref inputs "avahi")))
               (("Cmd\\(\"biosdecode")
                (format #f "Cmd(\"~a/sbin/biosdecode"
                        (assoc-ref inputs "dmidecode")))
               (("=cat")
                (format #f "=~a/bin/cat"
                        (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"chmod")
                (format #f "Cmd(\"~a/bin/chmod"
                        (assoc-ref inputs "coreutils")))
               (("\"chmod\"")
                (format #f "\"~a/bin/chmod\""
                        (assoc-ref inputs "coreutils")))
               (("\"chown\"")
                (format #f "\"~a/bin/chown\""
                        (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"cpuid")
                (format #f "Cmd(\"~a/bin/cpuid"
                        (assoc-ref inputs "cpuid")))
               (("Cmd\\(\"cpupower")
                (format #f "Cmd(\"~a/bin/cpupower"
                        (assoc-ref inputs "cpupower")))
               (("Cmd\\(\"curl")
                (format #f "Cmd(\"~a/bin/curl"
                        (assoc-ref inputs "curl")))
               (("Cmd = \"curl")
                (format #f "Cmd = \"~a/bin/curl"
                        (assoc-ref inputs "curl")))
               (("Cmd = \\(\"curl")
                (format #f "Cmd = (\"~a/bin/curl"
                        (assoc-ref inputs "curl")))
               (("\"date\"")
                (format #f "\"~a/bin/date\""
                        (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"dd")
                (format #f "Cmd(\"~a/bin/dd"
                        (assoc-ref inputs "coreutils")))
               (("\"dd ")
                (format #f "\"~a/bin/dd "
                        (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"df")
                (format #f "Cmd(\"~a/bin/df"
                        (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"dkms")
               (format #f "Cmd(\"~a/bin/dkms" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"dmesg")
                (format #f "Cmd(\"~a/bin/dmesg"
                        (assoc-ref inputs "util-linux")))
               (("Cmd\\(\"dmidecode")
                (format #f "Cmd(\"~a/sbin/dmidecode"
                        (assoc-ref inputs "dmidecode")))
               (("Cmd\\(\"dpkg")
                (format #f "Cmd(\"~a/bin/dpkg"
                        (assoc-ref inputs "dpkg")))
               #;(("echo")
               (format #f "~a/bin/echo" ;
               (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"edid-decode")
                (format #f "Cmd(\"~a/bin/edid-decode"
                        (assoc-ref inputs "edid-decode")))
               (("Cmd\\(\"efibootmgr")
                (format #f "Cmd(\"~a/sbin/efibootmgr"
                        (assoc-ref inputs "efibootmgr")))
               (("Cmd\\(\"efivar")
                (format #f "Cmd(\"~a/bin/efivar"
                        (assoc-ref inputs "efivar")))
               #;(("Cmd\\(\"eopkg")
               (format #f "Cmd(\"~a/bin/eopkg" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"ethtool")
                (format #f "Cmd(\"~a/sbin/ethtool"
                        (assoc-ref inputs "ethtool")))
               (("Cmd\\(\".*ethtool")
                (format #f "Cmd(\"~a/sbin/ethtool"
                        (assoc-ref inputs "ethtool")))
               (("Cmd\\(\"fdisk")
                (format #f "Cmd(\"~a/sbin/fdisk"
                        (assoc-ref inputs "util-linux")))
               #;(("Cmd\\(\"fglrxinfo")
               (format #f "Cmd(\"~a/bin/fglrxinfo" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"find")
                (format #f "Cmd(\"~a/bin/find"
                        (assoc-ref inputs "findutils")))
               (("Cmd\\(\"findmnt")
                (format #f "Cmd(\"~a/bin/findmnt"
                        (assoc-ref inputs "util-linux")))
               (("Cmd = \"findmnt")
                (format #f "Cmd = \"~a/bin/findmnt"
                        (assoc-ref inputs "util-linux")))
               (("Cmd\\(\"glxgears")
                (format #f "Cmd(\"~a/bin/glxgears"
                        (assoc-ref inputs "mesa-utils")))
               (("Cmd\\(\"glxinfo")
                (format #f "Cmd(\"~a/bin/glxinfo"
                        (assoc-ref inputs "mesa-utils")))
               #;(("grep")
               (format #f "~a/bin/grep" ;
               (assoc-ref inputs "grep")))
               (("`head")
                (format #f "`~a/bin/head"
                        (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"hciconfig")
               (format #f "Cmd(\"~a/bin/hciconfig" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"hcitool")
               (format #f "Cmd(\"~a/bin/hcitool" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"hddtemp")
                (format #f "Cmd(\"~a/sbin/hddtemp"
                        (assoc-ref inputs "hddtemp")))
               (("Cmd\\(\"hdparm")
                (format #f "Cmd(\"~a/sbin/hdparm"
                        (assoc-ref inputs "hdparm")))
               (("Cmd = \"hdparm")
                (format #f "Cmd = \"~a/bin/hdparm"
                        (assoc-ref inputs "hdparm")))
               #;(("Cmd\\(\"hp-probe")
               (format #f "Cmd(\"~a/bin/hp-probe" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"hwinfo")
               (format #f "Cmd(\"~a/bin/hwinfo" ;
               (assoc-ref inputs "hwinfo")))
               #;(("Cmd = \"hwinfo")
               (format #f "Cmd = \"~a/bin/hwinfo" ;
               (assoc-ref inputs "hwinfo")))
               (("Cmd\\(\"i2cdetect")
                (format #f "Cmd(\"~a/sbin/i2cdetect"
                        (assoc-ref inputs "i2c-tools")))
               (("Cmd\\(\"iasl")
                (format #f "Cmd(\"~a/bin/iasl"
                        (assoc-ref inputs "acpica")))
               (("Cmd\\(\"ifconfig")
                (format #f "Cmd(\"~a/bin/ifconfig"
                        (assoc-ref inputs "net-tools")))
               (("Cmd\\(\"inxi")
                (format #f "Cmd(\"~a/bin/inxi"
                        (assoc-ref inputs "inxi")))
               (("Cmd\\(\"iostat")
                (format #f "Cmd(\"~a/bin/iostat"
                        (assoc-ref inputs "sysstat")))
               (("Cmd\\(\"ip")
                (format #f "Cmd(\"~a/sbin/ip"
                        (assoc-ref inputs "iproute2")))
               (("Cmd\\(\".*ip")
                (format #f "Cmd(\"~a/sbin/ip"
                        (assoc-ref inputs "iproute2")))
               (("Cmd\\(\"iw")
                (format #f "Cmd(\"~a/sbin/iw"
                        (assoc-ref inputs "iw")))
               (("Cmd\\(\".*iw")
                (format #f "Cmd(\"~a/sbin/iw"
                        (assoc-ref inputs "iw")))
               #;(("Cmd\\(\"iwconfig")
               (format #f "Cmd(\"~a/bin/iwconfig" ;
               (assoc-ref inputs "foobar")))
               #;(("join")
               (format #f "~a/bin/join" ;
               (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"journalctl")
               (format #f "Cmd(\"~a/bin/journalctl" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"ls")
                (format #f "Cmd(\"~a/bin/ls"
                        (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"lsb_release")
               (format #f "Cmd(\"~a/bin/lsb_release" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"lsblk")
                (format #f "Cmd(\"~a/bin/lsblk"
                        (assoc-ref inputs "util-linux")))
               (("Cmd = \"lsblk")
                (format #f "Cmd = \"~a/bin/lsblk"
                        (assoc-ref inputs "util-linux")))
               (("Cmd\\(\"lscpu")
                (format #f "Cmd(\"~a/bin/lscpu"
                        (assoc-ref inputs "util-linux")))
               #;(("Cmd\\(\"lsinitrd")
               (format #f "Cmd(\"~a/bin/lsinitrd" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"lsmod")
                (format #f "Cmd(\"~a/bin/lsmod"
                        (assoc-ref inputs "module-init-tools")))
               (("Cmd\\(\"lspci")
                (format #f "Cmd(\"~a/sbin/lspci"
                        (assoc-ref inputs "pciutils")))
               #;(("Cmd\\(\"lspnp")
               (format #f "Cmd(\"~a/bin/lspnp" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"lsusb")
                (format #f "Cmd(\"~a/bin/lsusb"
                        (assoc-ref inputs "usbutils")))
               (("Cmd\\(\"mcelog")
                (format #f "Cmd(\"~a/sbin/mcelog"
                        (assoc-ref inputs "mcelog")))
               (("Cmd\\(\"md5sum")
                (format #f "Cmd(\"~a/bin/md5sum"
                        (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"megactl")
               (format #f "Cmd(\"~a/bin/megactl" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"memtester")
                (format #f "Cmd(\"~a/bin/memtester"
                        (assoc-ref inputs "memtester")))
               (("Cmd\\(\"mmcli")
                (format #f "Cmd(\"~a/bin/mmcli"
                        (assoc-ref inputs "modem-manager")))
               (("Cmd\\(\"modinfo")
                (format #f "Cmd(\"~a/sbin/modinfo"
                        (assoc-ref inputs "module-init-tools")))
               #;(("Cmd\\(\"monitor-get-edid")
               (format #f "Cmd(\"~a/bin/monitor-get-edid" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"mount")
                (format #f "Cmd(\"~a/bin/mount"
                        (assoc-ref inputs "util-linux")))
               #;(("Cmd\\(\"nm-tool")
               (format #f "Cmd(\"~a/bin/nm-tool" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"nmcli")
                (format #f "Cmd(\"~a/bin/nmcli"
                        (assoc-ref inputs "network-manager")))
               (("Cmd\\(\"numactl")
                (format #f "Cmd(\"~a/bin/numactl"
                        (assoc-ref inputs "numactl")))
               (("Cmd\\(\"nvme")
                (format #f "Cmd(\"~a/sbin/nvme"
                        (assoc-ref inputs "nvme-cli")))
               (("Cmd\\(\"opensc-tool")
                (format #f "Cmd(\"~a/bin/opensc-tool"
                        (assoc-ref inputs "opensc")))
               #;(("Cmd\\(\"optirun")
               (format #f "Cmd(\"~a/bin/optirun" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"pacman")
               (format #f "Cmd(\"~a/bin/pacman" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"pstree")
               (format #f "Cmd(\"~a/bin/pstree" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"rfkill")
                (format #f "Cmd(\"~a/sbin/rfkill"
                        (assoc-ref inputs "util-linux")))
               (("Cmd\\(\"route")
                (format #f "Cmd(\"~a/bin/route"
                        (assoc-ref inputs "net-tools")))
               (("Cmd\\(\"rpm")
                (format #f "Cmd(\"~a/bin/rpm"
                        (assoc-ref inputs "rpm")))
               (("Cmd\\(\"sane-find-scanner")
                (format #f "Cmd(\"~a/bin/sane-find-scanner"
                        (assoc-ref inputs "sane-backends")))
               (("Cmd\\(\"scanimage")
                (format #f "Cmd(\"~a/bin/scanimage"
                        (assoc-ref inputs "sane-backends")))
               (("Cmd\\(\"sensors")
                (format #f "Cmd(\"~a/bin/sensors"
                        (assoc-ref inputs "lm-sensors")))
               #;(("sha512sum")
               (format #f "~a/bin/sha512sum" ;
               (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"slabtop")
                (format #f "Cmd(\"~a/bin/slabtop"
                        (assoc-ref inputs "procps")))
               #;(("sleep")
               (format #f "~a/bin/sleep" ;
               (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"smartctl")
                (format #f "Cmd(\"~a/sbin/smartctl"
                        (assoc-ref inputs "smartmontools")))
               (("Cmd = \"smartctl")
                (format #f "Cmd = \"~a/bin/smartctl"
                        (assoc-ref inputs "smartmontools")))
               #;(("sort")
               (format #f "~a/bin/sort" ;
               (assoc-ref inputs "coreutils")))
               #;(("split")
               (format #f "~a/bin/split" ;
               (assoc-ref inputs "coreutils")))
               #;(("= stat")
               (format #f "= ~a/bin/stat" ;
               (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"superiotool")
               (format #f "Cmd(\"~a/bin/superiotool" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"swupd")
               (format #f "Cmd(\"~a/bin/swupd" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"systemctl")
               (format #f "Cmd(\"~a/bin/systemctl" ;
               (assoc-ref inputs "foobar")))
               #;(("Cmd\\(\"systemd-analyze")
               (format #f "Cmd(\"~a/bin/systemd-analyze" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"top")
                (format #f "Cmd(\"~a/bin/top"
                        (assoc-ref inputs "procps")))
               (("Cmd\\(\"udevadm")
                (format #f "Cmd(\"~a/bin/udevadm"
                        (assoc-ref inputs "eudev")))
               (("Cmd\\(\"uname")
                (format #f "Cmd(\"~a/bin/uname"
                        (assoc-ref inputs "coreutils")))
               #;(("unlink")
               (format #f "~a/bin/unlink" ;
               (assoc-ref inputs "coreutils")))
               #;(("Cmd\\(\"update-alternatives")
               (format #f "Cmd(\"~a/bin/update-alternatives" ;
               (assoc-ref inputs "foobar")))
               (("Cmd\\(\"upower")
                (format #f "Cmd(\"~a/bin/upower"
                        (assoc-ref inputs "upower")))
               (("Cmd\\(\"uptime")
                (format #f "Cmd(\"~a/bin/uptime"
                        (assoc-ref inputs "coreutils")))
               (("Cmd\\(\"usb-devices")
                (format #f "Cmd(\"~a/bin/usb-devices"
                        (assoc-ref inputs "usbutils")))
               (("Cmd\\(\"vainfo")
                (format #f "Cmd(\"~a/bin/vainfo"
                        (assoc-ref inputs "libva-utils")))
               (("Cmd\\(\"vdpauinfo")
                (format #f "Cmd(\"~a/bin/vdpauinfo"
                        (assoc-ref inputs "vdpauinfo")))
               (("Cmd\\(\"vulkaninfo")
                (format #f "Cmd(\"~a/bin/vulkaninfo"
                        (assoc-ref inputs "vulkan-tools")))
               (("Cmd\\(\"xdpyinfo")
                (format #f "Cmd(\"~a/bin/xdpyinfo"
                        (assoc-ref inputs "xdpyinfo")))
               (("Cmd\\(\"xinput")
                (format #f "Cmd(\"~a/bin/xinput"
                        (assoc-ref inputs "xinput")))
               (("Cmd\\(\"xrandr")
                (format #f "Cmd(\"~a/bin/xrandr"
                        (assoc-ref inputs "xrandr")))
               (("Cmd\\(\"xvinfo")
                (format #f "Cmd(\"~a/bin/xvinfo"
                        (assoc-ref inputs "xvinfo"))))))
         (delete 'configure)
         (add-after 'install 'wrap-programs
           (lambda* (#:key outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (bin-dir (string-append out "/bin/"))
                    (perl-lib (getenv "PERL5LIB")))
               (for-each
                (cut wrap-program <>
                     `("PERL5LIB" ":" prefix (,perl-lib)))
                (find-files bin-dir))))))))
    (inputs
     (list
      acpi
      acpica
      alsa-utils
      avahi
      bash-minimal
      coreutils
      cpuid
      cpupower
      curl
      dmidecode
      dpkg
      edid-decode
      efibootmgr
      efivar
      eudev
      findutils
      grep
      hddtemp
      hdparm
      hplip-minimal
      i2c-tools
      inxi
      iproute
      libva-utils
      lm-sensors
      mcelog
      memtester
      mesa-utils
      modem-manager
      module-init-tools
      net-tools
      network-manager
      numactl
      nvme-cli
      opensc
      pciutils
      perl-data-dumper
      perl-digest-sha
      perl-libwww
      ;;pnputils
      procps
      rpm
      sane-backends
      smartmontools
      sysstat
      upower
      usbutils
      util-linux
      vdpauinfo
      vulkan-tools
      xdpyinfo
      xinput
      xrandr
      xvinfo))
    (propagated-inputs
     ;; FIXME: HwInfo needs to be patched in 'hw-probe.pl'.
     (list
      hwinfo))
    (home-page "https://linux-hardware.org")
    (synopsis "Hardware Probe")
    (description "Hardware Probe is a tool to probe for hardware, check its
operability and find drivers.")
    (license license:lgpl2.1+)))

